package com.radar.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.radar.algorithm.Cacl;
import com.radar.algorithm.DenseLucaskanade;
import com.radar.algorithm.MathCommon;
import com.radar.algorithm.SemiLagrangian;
import com.radar.common.DateConstants;
import com.radar.common.DistinctByKey;
import com.radar.common.GisConstants;
import com.radar.common.ProductType;
import com.radar.exception.RadarDecodeError;
import com.radar.io.LatLonRadar;
import com.radar.task.cd.Constants;
import com.radar.visualize.RasterMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.bytedeco.javacpp.indexer.Indexer;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import ucar.ma2.ArrayInt;
import ucar.ma2.DataType;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import ucar.nc2.NetcdfFileWriter;
import ucar.nc2.Variable;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author: fy-wbj
 * @description: 电科院 latlon radar task
 * @date: 2021-04-21
 */

@Component
@Slf4j
public class ForecastTask {

    @Value("${rootPath}")
    private String rootPath;

    @Value("${ncPath}")
    private String ncPath;

    @Value("${tmpPath}")
    private String tmpPath;

//    @Scheduled(cron = "0 0/2 * * * ? ")
//    @Scheduled(fixedDelay = 1000 * 60)
    public void jobRun() {
        if (GisConstants.TEST) {
//            ncPath = "/Users/xx/Desktop/nc/";
//            tmpPath = "/Users/xx/Desktop/tmp/";
//            rootPath = "/Users/xx/Desktop/Radar/";
        }
        String[] prds = Constants.rootPath.split(";");
        for (String prdinfo : prds) {
            List<File> files = FileUtil.loopFiles(prdinfo, new RegexFileFilter("^Z_RADA_C_BABJ_(\\d{14})_P_ACHN.CREF000.(\\d{8}).(.*?).latlon$"));
            files = files.stream().filter(DistinctByKey
                    .distinctByKey(file ->
                            file.getName().split("\\.")[2] +
                                    file.getName().split("\\.")[3].substring(0,6)))
                    .sorted(Comparator
                            .comparing(file -> Long.parseLong(
                                    file.getName().split("\\.")[2] +
                                            file.getName().split("\\.")[3].substring(0,6))))
                    .collect(Collectors.toList());

            Map<String, List<File>> collect1 = FileUtil.loopFiles(prdinfo, new RegexFileFilter("^Z_RADA_C_BABJ_(\\d{14})_P_ACHN.CREF000.(\\d{8}).(.*?).latlon$"))
                    .stream().collect(Collectors
                            .groupingBy(file ->
                                    file.getName().split("\\.")[2] +
                                            file.getName().split("\\.")[3].substring(0,6)));

            Map<String, List<File>> collect = files
                    .stream()
                    .collect(Collectors
                            .groupingBy(file ->
                                    file.getName().split("\\.")[2] +
                                            file.getName().split("\\.")[3].substring(0,6)));
            log.info("start loop dky forecasttask files length : {}", files.size());
            files.forEach(ft -> {
                File okfile = new File(ncPath + File.separator + "OK" + File.separator + ft.getName() + ".OK");
                if (FileUtil.exist(okfile)){
                    return;
                } else {
                    FileUtil.touch(okfile);
                }

                String dt = ft.getName().split("\\.")[2] + ft.getName().split("\\.")[3].substring(0,6);
                File file = getFile(collect.get(dt));
                String format = dt.length() == 12 ? DateConstants.DATE_FORMAT_YYYYMMDDHHMM : DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS;
                Date date = DateUtil.parse(dt, format);
                date = DateUtil.offsetMinute(date, -12);
                List<File> list1 = collect1.get(DateUtil.format(date, "yyyyMMddHHmmss"));
                if (list1 == null) {
                    return;
                }
                try {
                    log.info("start parse latlon radar file : {} , step : {} ,next radar file : {}", ft, 12, file);
                    parseItem(getFile(list1), file);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }

    public static void writeNC(String ncFile, double[] xarray, double[] yarray, int step, int num, Date date, float[][][] data) throws Exception {
        NetcdfFileWriter write = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf4, ncFile);
        NetcdfFile netcdfFile = null;
        if (write.isDefineMode()) {
            write.create();
            netcdfFile = write.getNetcdfFile();
        }

        // add global attriubte
        List<Attribute> globalAttr = new ArrayList<>();
        globalAttr.add(new Attribute("title", "OPENCV FLOW FORECAST RADAR STRUCT"));

        globalAttr.add(new Attribute("fileName", new File(ncFile).getName()));
        Attribute references = new Attribute("references", "https://github.com/CyanideCN/PyCINRAD");
        globalAttr.add(references);
        globalAttr.add(new Attribute("description", ""));
        globalAttr.add(new Attribute("flow_step", step));
        globalAttr.add(new Attribute("flow_num,", num));
        globalAttr.add(new Attribute("scan_time", DateUtil.format(date, DateConstants.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI)));
        for (Attribute attribute : globalAttr) {
            netcdfFile.addAttribute(netcdfFile.getRootGroup(), attribute);
        }
        write.setRedefineMode(true);
        // add lon lat alt Dimension
        write.addDimension(null, "Longitude", xarray.length);
        write.addDimension(null, "Latitude", yarray.length);
        write.addDimension(null, "ForecastTime", num);

        Variable v1 = write.addVariable(null, "Longitude", DataType.DOUBLE, "Longitude");
        v1.addAttribute(new Attribute("units", "degrees_east"));
        v1.addAttribute(new Attribute("actual_range", Arrays.asList(xarray[0], xarray[xarray.length - 1])));

        Variable v2 = write.addVariable(null, "Latitude", DataType.DOUBLE, "Latitude");
        v2.addAttribute(new Attribute("units", "degrees_north"));
        v2.addAttribute(new Attribute("actual_range", Arrays.asList(yarray[0], yarray[yarray.length - 1])));

        int tarray[] = new int[num];
        IntStream.range(0, tarray.length).forEach(i -> tarray[i] = (i + 1) * step);
        Variable v3 = write.addVariable(null, "ForecastTime", DataType.INT, "ForecastTime");
        v3.addAttribute(new Attribute("units", "minute"));

        Variable flow = write.addVariable(null, "FLOW", DataType.FLOAT, Arrays.asList(
                netcdfFile.findDimension("ForecastTime"),
                netcdfFile.findDimension("Latitude"),
                netcdfFile.findDimension("Longitude")));

        flow.addAttribute(new Attribute("missing_value", GisConstants.UNDEF));
//        flow.addAttribute(new Attribute("range_value", (byte) -100));
//        flow.addAttribute(new Attribute("add_offset", 32.5f));
//        flow.addAttribute(new Attribute("scale_factor", 0.5f));

        flow.addAttribute(new Attribute("full_name", ProductType.REF.getFullName()));
        flow.addAttribute(new Attribute("units", ProductType.REF.getUnit()));

        write.setRedefineMode(false);

        ArrayInt arrayInt = new ArrayInt.D1(tarray.length);
        for (int i = 0; i < tarray.length; ++i) {
            arrayInt.setDouble(i, tarray[i]);
        }
        write.write(v1, MathCommon.toArray(xarray));
        write.write(v2, MathCommon.toArray(yarray));
        write.write(v3, arrayInt);

        // write byte data
        write.write(flow, MathCommon.toFloatArray(data));
        netcdfFile.close();
        write.abort();
        write.close();
    }

    public static void main(String[] args) throws IOException, RadarDecodeError {
//        String dir = "D:\\dkydata\\";
//        List<File> files = FileUtil.loopFiles(dir, new RegexFileFilter("^Z_RADA_C_BABJ_(\\d{14})_P_ACHN.CREF000.(\\d{8}).(\\d{2})0000.latlon$"));
//        files = files.stream().filter(DistinctByKey.distinctByKey(file -> file.getName().split("\\.")[2] + file.getName().split("\\.")[3]))
//                .sorted(Comparator.comparing(file -> Long.parseLong(file.getName().split("\\.")[2] + file.getName().split("\\.")[3]))).collect(Collectors.toList());
//        Map<String, List<File>> collect1 = FileUtil.loopFiles(dir, new RegexFileFilter("^Z_RADA_C_BABJ_(\\d{14})_P_ACHN.CREF000.(\\d{8}).(\\d{2})4800.latlon$")).stream().collect(Collectors.groupingBy(file -> file.getName().split("\\.")[2] + file.getName().split("\\.")[3]));
//        Map<String, List<File>> collect = files.stream().collect(Collectors.groupingBy(file -> file.getName().split("\\.")[2] + file.getName().split("\\.")[3]));
//        files.forEach(ft -> {
//            String dt = ft.getName().split("\\.")[2] + ft.getName().split("\\.")[3];
//            File file = getFile(collect.get(dt));
//            String format = dt.length() == 12 ? DateConstants.DATE_FORMAT_YYYYMMDDHHMM : DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS;
//
//            Date date = DateUtil.parse(dt, format);
//            int hour = DateUtil.hour(date, true);
//            if (hour % 12 != 0) {
//                return;
//            }
//            date = DateUtil.offsetMinute(date, -12);
//            List<File> list1 = collect1.get(DateUtil.format(date, "yyyyMMddHHmmss"));
//            if (list1 == null) {
//                return;
//            }
//            try {
//                parseItem(getFile(list1), file);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        });
    }

    public File getFile(List<File> list) {
        if (list.size() == 0) {
            return null;
        }
        if (list.size() == 1) {
            return list.get(0);
        }
        if (list.size() == 2) {
            return Long.parseLong(list.get(0).getName().split("_")[4]) > Long.parseLong(list.get(1).getName().split("_")[4]) ? list.get(0) : list.get(1);
        }
        return null;
    }

    public void parseItem(File fpre, File file) throws RadarDecodeError, IOException {
        String output = ncPath + File.separator;

        log.info("start parse file : {}, prefile : {}", file.getAbsolutePath(), fpre.getAbsolutePath());
        String date = file.getName().split("\\.")[2] + file.getName().split("\\.")[3].substring(0,6);
//        date= DateUtil.format(DateUtil.offsetMonth(DateUtil.parse(date, DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS), 3),DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS);
        if (FileUtil.isDirectory(output + date + File.separator)) {
            return;
        }
        LatLonRadar radar = new LatLonRadar();
        radar.parse(file.getAbsolutePath());

        LatLonRadar radar1 = new LatLonRadar();
        radar1.parse(fpre.getAbsolutePath());

        log.info("draw this file gray png file : {}", file.getName());
        RasterMap rasterMap = new RasterMap(null);

        for (int i = 0; i < radar.data.length; i++) {
            for (int j = 0; j < radar.data[0].length; j++) {
                radar.data[i][j] = radar.data[i][j] < 5 ? GisConstants.UNDEF : radar.data[i][j];
                radar1.data[i][j] = radar1.data[i][j] < 5 ? GisConstants.UNDEF : radar1.data[i][j];
            }
        }
        double[][] data = radar.data;
        double[][] data1 = radar1.data;

        BufferedImage bufferedImage;

        FileUtil.mkdir(output + date + File.separator);

//        bufferedImage = rasterMap.drawSingleRaster(data, ProductType.REF, new Color(0, 0, 0, 0));
//        ImageIO.write(bufferedImage, "png", new File(output + date + File.separator + date + "_CR_0.png"));

        data = Cacl.nineMedianFilter(data);
        data1 = Cacl.nineMedianFilter(data1);

        bufferedImage = rasterMap.drawSingleRaster(data, ProductType.REFGRAY, new Color(0, 0, 0, 0));
        ImageIO.write(bufferedImage, "png", new File(output + date + File.separator + "CR_GRAY.png"));

        bufferedImage = rasterMap.drawSingleRaster(data1, ProductType.REFGRAY, new Color(0, 0, 0, 0));
        ImageIO.write(bufferedImage, "png", new File(output + date + File.separator + "PRE_CR_GRAY.png"));

        try {
            String format = date.length() == 12 ? DateConstants.DATE_FORMAT_YYYYMMDDHHMM : DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS;
            Date dt = DateUtil.parse(date, format);

            forecast(output + date + File.separator + "PRE_CR_GRAY.png",
                    output + date + File.separator + "CR_GRAY.png", data, date, radar, dt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void forecast(String preImg, String nextImg, double[][] data, String date, LatLonRadar radar, Date dt) throws Exception {
        if (!FileUtil.exist(preImg) || !FileUtil.exist(nextImg)) {
            return;
        }
        int offset = 4;
        String output = ncPath + File.separator;
        Mat ff1 = opencv_imgcodecs.imread(preImg);
        Mat ff2 = opencv_imgcodecs.imread(nextImg);
        Mat prvs = ff1.clone();
        Mat next = ff1.clone();
        opencv_imgproc.cvtColor(ff1, prvs, opencv_imgproc.COLOR_BGR2GRAY);
        opencv_imgproc.cvtColor(ff2, next, opencv_imgproc.COLOR_BGR2GRAY);

        int step = 8;

        int w = Math.min(prvs.size().get(0), next.size().get(0)) / step;
        int h = Math.min(prvs.size().get(1), next.size().get(1)) / step;

        double[][] pre = new double[h][w];
        double[][] nex = new double[h][w];
        Indexer indexer = prvs.createIndexer();
        Indexer indexer1 = next.createIndexer();

        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                pre[i][j] = indexer.getDouble(i * step, j * step);
                if (pre[i][j] == 255) {
                    pre[i][j] = 0;
                }
                nex[i][j] = indexer1.getDouble(i * step, j * step);
                if (nex[i][j] == 255) {
                    nex[i][j] = 0;
                }
            }
        }

        double[][][] cacl = DenseLucaskanade.cacl(new double[][][]{pre, nex});
        double[][] uu = cacl[0];
        double[][] vv = cacl[1];
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                uu[i][j] = uu[i][j] * (6.0 / offset);
                vv[i][j] = vv[i][j] * (6.0 / offset);
            }
        }

        uu = Cacl.nineMedianFilter(uu);
        uu = Cacl.nineMedianFilter(uu);
        vv = Cacl.nineMedianFilter(vv);
        vv = Cacl.nineMedianFilter(vv);

        double[][] u = new double[uu.length * step][uu[0].length * step];
        double[][] v = new double[uu.length * step][uu[0].length * step];
        for (int i = 0; i < u.length; i++) {
            for (int j = 0; j < u[0].length; j++) {
                u[i][j] = uu[i / step][j / step];
                v[i][j] = vv[i / step][j / step];
            }
        }

        double[][] decode = data;
        if (decode.length == u.length && decode[0].length == u[0].length) {

        } else {
            double[][] z = new double[u.length][u[0].length];
            for (int i = 0; i < u.length; i++) {
                for (int j = 0; j < u[0].length; j++) {
                    if (i >= decode.length || j >= decode[0].length) {
                        z[i][j] = GisConstants.UNDEF;
                    } else {
                        z[i][j] = decode[i][j];
                    }
                }
            }
            decode = z;
        }
        for (int i = 0; i < u.length; i++) {
            for (int j = 0; j < u[0].length; j++) {
                u[i][j] = uu[i / step][j / step];
                v[i][j] = vv[i / step][j / step];
            }
        }


        SemiLagrangian semiLagrangian = new SemiLagrangian();
        int t = 20;
        int zstep = 2;
        double[][] rdata = new double[decode.length / zstep][decode[0].length / zstep];
        double[][] nu = new double[decode.length / zstep][decode[0].length / zstep];
        double[][] nv = new double[decode.length / zstep][decode[0].length / zstep];
        for (int i = 0; i < decode.length / zstep; i++) {
            for (int j = 0; j < decode[0].length / zstep; j++) {
                rdata[i][j] = radar.data[i * zstep][j * zstep];
                nu[i][j] = u[i * zstep][j * zstep];
                nv[i][j] = v[i * zstep][j * zstep];
            }
        }

        float[][][] extrapolate = semiLagrangian.extrapolate(MathCommon.doubleToFloat(rdata), MathCommon.doubleToFloat(nu), MathCommon.doubleToFloat(nv), t);
        byte[][][] flowData = new byte[extrapolate.length][extrapolate[0].length][extrapolate[0][0].length];
        for (int i = 0; i < t; i++) {
            for (int j = 0; j < rdata.length; j++) {
                for (int k = 0; k < rdata[0].length; k++) {
                    extrapolate[i][j][k] = extrapolate[i][j][k] == 0 || Float.isNaN(extrapolate[i][j][k]) ? GisConstants.UNDEF : extrapolate[i][j][k];
                    if (extrapolate[i][j][k] == GisConstants.UNDEF) {
                        flowData[i][j][k] = -128;
                    } else {
                        flowData[i][j][k] = MathCommon.CodeRef((double) extrapolate[i][j][k]);
                    }
                }
            }
        }

        double xarray[] = new double[nu[0].length];
        double yarray[] = new double[nu.length];
        IntStream.range(0, xarray.length).forEach(i -> xarray[i] = radar.lons + ((radar.lone - radar.lons) / xarray.length) * i);
        IntStream.range(0, yarray.length).forEach(i -> yarray[i] = radar.late - ((radar.late - radar.lats) / yarray.length) * i);
        writeNC(output + date + File.separator + "forecast.nc", xarray, yarray, 6, t, dt, extrapolate);
    }

    public void processItem(File file) throws Exception {
        log.info("start parse lonlat radar file : {}", file.getName());
        String dt = file.getName().split("\\.")[2] + file.getName().split("\\.")[3].substring(0,6);
        String format = dt.length() == 12 ? DateConstants.DATE_FORMAT_YYYYMMDDHHMM : DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS;
        Date date = DateUtil.parse(dt, format);
        LatLonRadar radar = new LatLonRadar();
        radar.parse(file.getAbsolutePath());
        log.info("draw this file gray png file : {}", file.getName());

        for (int i = 0; i < radar.data.length; i++) {
            for (int j = 0; j < radar.data[0].length; j++) {
                radar.data[i][j] = radar.data[i][j] < 5 ? GisConstants.UNDEF : radar.data[i][j];
            }
        }
        radar.data = Cacl.nineMedianFilter(radar.data);
        radar.data = Cacl.nineMedianFilter(radar.data);
        radar.data = Cacl.nineMedianFilter(radar.data);
        RasterMap rasterMap = new RasterMap(null);
        BufferedImage bufferedImage = rasterMap.drawSingleRaster(radar.data, ProductType.REFGRAY, new Color(0, 0, 0, 0));
        String outFile = tmpPath + File.separator + dt + "_" + file.getName().split("\\.")[1] + "_CR_GRAY.png";
        ImageIO.write(bufferedImage, "png", new File(outFile));

        // find pre Img
        String preImage = tmpPath + File.separator + (DateUtil.format(DateUtil.offsetMinute(date, -6), format)) + "_" + file.getName().split("\\.")[1] + "_CR_GRAY.png";
        if (!FileUtil.exist(preImage)) {
            log.error(" not found pre cr gray img file : {}", file.getName());
            return;
        }
        long time = System.currentTimeMillis();
        log.info(" start open cv flow forecast radar file : {}", file.getName());
        Mat ff1 = opencv_imgcodecs.imread(preImage);
        Mat ff2 = opencv_imgcodecs.imread(outFile);
        Mat prvs = ff1.clone();
        Mat next = ff1.clone();
        opencv_imgproc.cvtColor(ff1, prvs, opencv_imgproc.COLOR_BGR2GRAY);
        opencv_imgproc.cvtColor(ff2, next, opencv_imgproc.COLOR_BGR2GRAY);
        int w = prvs.size().get(0);
        int h = prvs.size().get(1);
        double[][] pre = new double[h / 2][w / 2];
        double[][] nex = new double[h / 2][w / 2];
        Indexer indexer = prvs.createIndexer();
        Indexer indexer1 = next.createIndexer();
        for (int i = 0; i < h / 2; i++) {
            for (int j = 0; j < w / 2; j++) {
                pre[i][j] = indexer.getDouble(i * 2, j * 2);
                if (pre[i][j] == 255) {
                    pre[i][j] = 0;
                }
                nex[i][j] = indexer1.getDouble(i * 2, j * 2);
                if (nex[i][j] == 255) {
                    nex[i][j] = 0;
                }
            }
        }
        double[][][] cacl = DenseLucaskanade.cacl(new double[][][]{pre, nex});
        double[][] u = cacl[0];
        double[][] v = cacl[1];
        for (int i = 0; i < h / 2; i++) {
            for (int j = 0; j < w / 2; j++) {
                u[i][j] = u[i][j] * 2;
                v[i][j] = v[i][j] * 2;
            }
        }
        SemiLagrangian semiLagrangian = new SemiLagrangian();
        int t = 20;
        double[][] rdata = new double[h / 2][w / 2];
        for (int i = 0; i < h / 2; i++) {
            for (int j = 0; j < w / 2; j++) {
                rdata[i][j] = radar.data[i * 2][j * 2];
            }
        }

        float[][][] extrapolate = semiLagrangian.extrapolate(MathCommon.doubleToFloat(rdata), MathCommon.doubleToFloat(u), MathCommon.doubleToFloat(v), t);
        byte[][][] flowData = new byte[extrapolate.length][extrapolate[0].length][extrapolate[0][0].length];
        // write nc file
        String ncFile = ncPath + File.separator + file.getName().split("\\.")[2] + File.separator + dt + ".nc";
        if (!FileUtil.isDirectory(ncPath + File.separator + file.getName().split("\\.")[2] + File.separator)) {
            FileUtil.mkdir(ncPath + File.separator + file.getName().split("\\.")[2] + File.separator);
        }
        if (!FileUtil.isDirectory(ncPath + File.separator + file.getName().split("\\.")[2] + File.separator + file.getName().split("\\.")[3])) {
            FileUtil.mkdir(ncPath + File.separator + file.getName().split("\\.")[2] + File.separator + file.getName().split("\\.")[3]);
        }
        log.info("end semiLagrangian cacl time: {} start write nc file : {} ", System.currentTimeMillis() - time, ncFile);
        for (int i = 0; i < t; i++) {
            for (int j = 0; j < h / 2; j++) {
                for (int k = 0; k < w / 2; k++) {
                    if (extrapolate[i][j][k] == 0 || extrapolate[i][j][k] == Float.NaN) {
                        flowData[i][j][k] = -128;
                    } else {
                        flowData[i][j][k] = MathCommon.CodeRef((double) extrapolate[i][j][k]);
                    }
                }
            }
            rasterMap = new RasterMap(null);
            bufferedImage = rasterMap.drawSingleRaster(MathCommon.decode(flowData[i], ProductType.REF), new Color(0, 0, 0, 0));
            try {
                ImageIO.write(bufferedImage, "png", new File(ncPath + File.separator + file.getName().split("\\.")[2] + File.separator + file.getName().split("\\.")[3] + File.separator + "CR_" + (i + 1) + ".png"));
            } catch (Exception e) {
                System.out.println();
            }

        }
        double xarray[] = new double[u[0].length];
        double yarray[] = new double[u.length];
        IntStream.range(0, xarray.length).forEach(i -> xarray[i] = radar.lons + ((radar.lone - radar.lons) / xarray.length) * i);
        IntStream.range(0, yarray.length).forEach(i -> yarray[i] = radar.late - ((radar.late - radar.lats) / yarray.length) * i);
        // TODO
//        writeNC(ncFile, xarray, yarray, 6, t, date, flowData);
    }




}
